package com.youlu.campus.service.qa.impl;

import com.youlu.campus.entity.SystemNickNameAndHeaderImage;
import com.youlu.campus.entity.UserQaRanking;
import com.youlu.campus.entity.WechatMiniUserPO;
import com.youlu.campus.service.wechat.SystemNickNameAndHeaderImageService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
public class UserQaRankingService {

    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private SystemNickNameAndHeaderImageService systemNickNameAndHeaderImageService;

    @Async
    public void updateByUserId(UserQaRanking userQaRanking){
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userQaRanking.getUserId()));
        query.addCriteria(Criteria.where("activityId").is(userQaRanking.getActivityId()));
        Update update = new Update();
        update.set("updatedTime",new Date());
        if(StringUtils.isNotBlank(userQaRanking.getUniversityName())){
            update.set("universityName",userQaRanking.getUniversityName());
        }
        if(StringUtils.isNotBlank(userQaRanking.getUniversityId())){
            update.set("universityId",userQaRanking.getUniversityId());
        }
        if(StringUtils.isNotBlank(userQaRanking.getNickName())){
            update.set("nickName",userQaRanking.getNickName());
        }
        if(StringUtils.isNotBlank(userQaRanking.getHeadImageUrl())){
            update.set("headImageUrl",userQaRanking.getHeadImageUrl());
        }
        this.mongoTemplate.updateMulti(query,update,UserQaRanking.class);
    }


    @Async
    public void saveOrUpdate(UserQaRanking userQaRanking) {
        String activityId = userQaRanking.getActivityId();
        String userId = userQaRanking.getUserId();
        String qaInfoId = userQaRanking.getQaInfoId();
        if (Objects.isNull(userQaRanking) || StringUtils.isBlank(activityId) || StringUtils.isBlank(userId) || StringUtils.isBlank(qaInfoId)) {
            log.error("【新增答题分数】参数错误 userId qaInfoId activityId 错误");
            return;
        }
        if (userQaRanking.getQaScore().compareTo(0D) == 0) {
            return;
        }

        log.info("【新增答题分数】 userId -> {} | qaInfoId - > {} | activityId -> {}",userId,qaInfoId,activityId);
        Update update = new Update();
        Date now = new Date();
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId));
        query.addCriteria(Criteria.where("activityId").is(activityId));
        query.addCriteria(Criteria.where("qaInfoId").is(qaInfoId));
        UserQaRanking exists = this.mongoTemplate.findOne(query, UserQaRanking.class);
        if(Objects.isNull(exists)){
            update.set("createdTime",now);
            if(Objects.nonNull(userQaRanking.getQaScore())){
                update.set("qaScore",userQaRanking.getQaScore());
            }

        }else{
            if(Objects.nonNull(userQaRanking.getQaScore())){
                if(userQaRanking.getQaScore().compareTo(exists.getQaScore())==1){
                    update.set("qaScore",userQaRanking.getQaScore());
                }
            }
        }
        update.set("updatedTime",now);
        if(StringUtils.isNotBlank(userQaRanking.getUniversityId())){
            update.set("universityId",userQaRanking.getUniversityId());
        }
        if(StringUtils.isNotBlank(userQaRanking.getUniversityName())){
            update.set("universityName",userQaRanking.getUniversityName());
        }
        if(StringUtils.isNotBlank(userQaRanking.getNickName())){
            update.set("nickName",userQaRanking.getNickName());
        }
        if(StringUtils.isNotBlank(userQaRanking.getHeadImageUrl())){
            update.set("headImageUrl",userQaRanking.getHeadImageUrl());
        }
        if(Objects.nonNull(userQaRanking.getQaNo())){
            update.set("qaNo",userQaRanking.getQaNo());
        }
        if(StringUtils.isNotBlank(userQaRanking.getQaTitle())){
            update.set("qaTitle",userQaRanking.getQaTitle());
        }
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
        findAndModifyOptions.upsert(Boolean.TRUE);
        this.mongoTemplate.findAndModify(query,update,findAndModifyOptions,UserQaRanking.class);
    }

    public List<UserQaRanking> findByUser(String userId, String activityId) {
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId).and("activityId").is(activityId));
//        query.with(new Sort(Sort.Direction.ASC, "qaNo"));
        Sort sort=Sort.by(Sort.Direction.ASC, "qaNo");
        query.with(sort);
        return mongoTemplate.find(query, UserQaRanking.class);
    }

    public List<UserQaRanking> findByActivityidQaid(String activityId, String qaId) {
        Query query = new Query().addCriteria(Criteria.where("qaInfoId").is(qaId).and("activityId").is(activityId));
//        query.with(new Sort(Sort.Direction.DESC, "qaScore"));
        Sort sort=Sort.by(Sort.Direction.DESC, "qaScore");
        query.with(sort);
        query.limit(10);
        return mongoTemplate.find(query, UserQaRanking.class);
    }

    public Page<UserQaRanking> findQaScoreRankingByActivityId(String activityId, String qaInfoId,Integer pageNo,
                                                              Integer pageSize,String platform) {
        Query query = new Query().addCriteria(Criteria.where("qaInfoId").is(qaInfoId).and("activityId").is(activityId));
        PageRequest pageRequest = PageRequest.of(pageNo - 1, pageSize);
//        query.with(new Sort(Sort.Direction.DESC, "qaScore"));
        Sort sort=Sort.by(Sort.Direction.DESC, "qaScore");
        query.with(sort);
        query.limit(100);
        List<UserQaRanking> userQaRankingList = mongoTemplate.find(query, UserQaRanking.class);
        if(CollectionUtils.isEmpty(userQaRankingList)){
            return PageableExecutionUtils.getPage(userQaRankingList, pageRequest, () -> 0L);
        }
        userQaRankingList = userQaRankingList.stream().skip((pageNo-1)*pageSize).limit(pageSize).collect(Collectors.toList());
        if("wechat-mini".equals(platform)){
            List<String> uids = userQaRankingList.stream().map(UserQaRanking::getUserId).distinct().collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(uids)){
                Query userQuery = new Query().addCriteria(Criteria.where("accountInfoId").in(uids));
                List<WechatMiniUserPO> userPOList = mongoTemplate.find(userQuery,WechatMiniUserPO.class);
                Map<String ,WechatMiniUserPO> ma = userPOList.stream().collect(Collectors.toMap(WechatMiniUserPO::getAccountInfoId, Function.identity(),(o1,o2)->o2));
                userQaRankingList.forEach(item->{
                    WechatMiniUserPO po = ma.get(item.getUserId());
                    if(po != null){
                        if(po.getAvatarUrl() != null && po.getAvatarUrl().startsWith("https://qiniu.gqgood.com")) {
                            item.setNickName(po.getNickName());
                            item.setHeadImageUrl(po.getAvatarUrl());
                        }else{
                            // 随机获取一张系统图像
                            SystemNickNameAndHeaderImage image = systemNickNameAndHeaderImageService.getRandom();
                            String nickName = StringUtils.isBlank(po.getNickName())?image.getNickName():po.getNickName();
                            updateMiniLogo(image.getAvatarUrl(),nickName,po.getId());
                            item.setNickName(nickName);
                            item.setHeadImageUrl(image.getAvatarUrl());
                        }
                    }
                });
            }
        }
        return PageableExecutionUtils.getPage(userQaRankingList, pageRequest, () -> 2);
    }

    public void updateMiniLogo(String avatarUrl,String nickName,String id){
        Query query = new Query().addCriteria(Criteria.where("id").is(id));
        Update update = new Update();
        update.set("avatarUrl",avatarUrl);
        update.set("nickName",nickName);
        update.set("validLogo",true);
        mongoTemplate.updateFirst(query,update,WechatMiniUserPO.class);
    }
}
